package de.milo.map;

import de.milo.map.tile.MapTile;

/**
 * This class represents an enviroment in the game.
 * @author Mizi
 *
 */
public class Map
{
	private MapTile tileData[][][];
	
	/**
	 * Creates a new map with the given width and height
	 * and the given number of layers.
	 * @param width the width of the map in tiles
	 * @param height the height of the map in tiles
	 * @param layer the number of layers
	 */
	public Map(int width, int height, int layer)
	{
		if(width < 1) {
			new IllegalArgumentException("A map needs a width of at least 1.");
		}
		if(height < 1) {
			new IllegalArgumentException("A map needs a height of at least 1.");
		}
		if(layer < 1) {
			new IllegalArgumentException("A map needs at least 1 layer.");
		}
		this.tileData = new MapTile[width][height][layer];
	}
	
	/**
	 * Returns the width of the map in tiles.
	 * @return the width of the map in tiles
	 */
	public int getWidth()
	{
		return tileData.length;
	}
	
	/**
	 * Returns the height of the map in tiles.
	 * @return the height of the map in tiles
	 */
	public int getHeight()
	{
		return tileData[0].length;
	}
	
	/**
	 * Returns the number of layers.
	 * @return the number of layers
	 */
	public int getLayerCount()
	{
		return tileData[0][0].length;
	}
	
	/**
	 * Returns an excerpt of the map. All tiles of
	 * the returned map are references to the original
	 * map.
	 * @param x the x-coordinate of the map excerpt
	 * @param y the y-coordinate of the map excerpt
	 * @param width the width of the map excerpt
	 * @param height the height of the map excerpt
	 * @return an excerpt of the original map
	 */
	public Map getMapExcerpt(int x, int y, int width, int height)
	{
		Map ret = new Map(width, height, this.getLayerCount());
		for(int layer = 0; layer < this.getLayerCount(); ++layer) {
			for(int i = 0; i < width; ++i) {
				for(int j = 0; j < height; ++j) {
					ret.setTile(i, j, layer, tileData[i + x][j + y][layer]);
				}
			}
		}
		return ret;
	}
	
	/**
	 * Returns the tile on the given location of the map.
	 * @param x the x-position of the tile
	 * @param y the y-position of the tile
	 * @param layer the layer this tile belongs to
	 * @return the tile on the given location
	 */
	public MapTile getTile(int x, int y, int layer)
	{
		return tileData[x][y][layer];
	}
	
	/**
	 * Sets the tile on the given location of the map.
	 * @param x the x-position of the tile
	 * @param y the y-position of the tile
	 * @param layer the layer this tile belongs to
	 * @param tile the tile to set
	 */
	public void setTile(int x, int y, int layer, MapTile tile)
	{
		tileData[x][y][layer] = tile;
	}
}
